/**
 * 项目名：	Rumba Plan
 * 
 * 版权所有(C)，上海海鼎信息工程股份有限公司，2006，所有权利保留。
 * 
 * 文件名：	ViewOrganizationSystem.java
 * 模块说明：	
 * 修改历史：
 * 2006-6-27 - lxm - 创建。
 */
package com.hd123.rumba.action.organization;

import java.util.ArrayList;
import java.util.List;

import net.sf.hibernate.HibernateException;

import com.hd123.rumba.action.user.ViewRoleSystem;
import com.hd123.rumba.action.user.ViewUserSystem;
import com.hd123.rumba.cartridge.FVRumbaSystem;
import com.hd123.rumba.exception.BusinessException;
import com.hd123.rumba.organization.COrganization;
import com.hd123.rumba.organization.IOrganization;
import com.hd123.rumba.organization.biz.BOrganization;
import com.hd123.rumba.organization.biz.IBOrganizationMgr;
import com.hd123.rumba.request.Action;
import com.hd123.rumba.request.ActionConstants;
import com.hd123.rumba.sql.SCE;
import com.hd123.rumba.sql.biz.BSQLSubquery;
import com.hd123.rumba.user.IUser;
import com.hd123.rumba.user.PE;
import com.hd123.rumba.util.LevelCode;

/**
 * 组织 | Action | FVRumbaSystem
 * 
 * @author lxm
 * 
 */
public class ViewOrganizationSystem extends BaseViewOrganization implements Action {

  public static final String CAPTION_VIEW = "组织维护";

  /* 权限常量 */
  public static final String FUNCV_PREFIX = FVRumbaSystem.FUNCV_PREFIX;
  public static final String PERMISSION_SELF_VIEW = FUNCV_PREFIX + ".本组织.查看权";
  public static final String PERMISSION_SELF_EDIT = FUNCV_PREFIX + ".本组织.编辑权";
  public static final String PERMISSION_UPPER_VIEW = FUNCV_PREFIX + ".上级组织.查看权";
  public static final String PERMISSION_BROTHER_VIEW = FUNCV_PREFIX + ".兄弟组织.查看权";
  public static final String PERMISSION_LOWER_CREATE = FUNCV_PREFIX + ".下级组织.新增权";
  public static final String PERMISSION_LOWER_VIEW = FUNCV_PREFIX + ".下级组织.查看权";
  public static final String PERMISSION_LOWER_EDIT = FUNCV_PREFIX + ".下级组织.编辑权";
  public static final String PERMISSION_LOWER_DELETE = FUNCV_PREFIX + ".下级组织.删除权";
  public static final String PERMISSION_LOWER_RECYCLE_VIEW = FUNCV_PREFIX + ".下级组织.回收站.查看权";
  public static final String PERMISSION_LOWER_RECYCLE_EDIT = FUNCV_PREFIX + ".下级组织.回收站.编辑权";
  public static final String PERMISSION_LOWER_RECYCLE_UNDELETE = FUNCV_PREFIX + ".下级组织.回收站.恢复删除权";

  /* Templates */
  protected static final String TEMPLATE_HOME = "organization/OrganizationsHome.jsp";

  public String execute() throws Exception {
    String url = ActionConstants.NOTIMPLEMENTED;
    dd.put("viewName", "ViewOrganizationSystem");

    String startnode = (String) dd.getFormValue("start");
    if (startnode == null)
      startnode = "home";
    if ("home".equals(startnode))
      url = this.executeWithPermission("home", PERMISSION_SELF_VIEW);
    else if ("view".equals(startnode))
      url = this.executeWithPermission("view", null);
    else if ("list".equals(startnode)) {
      String isRecycleStr = (String) dd.getFormValue("isRecycle");
      if (isRecycleStr == null)
        isRecycleStr = "FALSE";
      Boolean isRecycle = "TRUE".equalsIgnoreCase(isRecycleStr) ? Boolean.TRUE : Boolean.FALSE;
      if (isRecycle.booleanValue())
        url = this.executeWithPermissions("listRecycle", PE.OR(new PE[] {
            PE.P(PERMISSION_SELF_VIEW), PE.P(PERMISSION_UPPER_VIEW), PE.P(PERMISSION_BROTHER_VIEW),
            PE.P(PERMISSION_LOWER_VIEW) }));
      else
        url = this.executeWithPermission("list", PERMISSION_LOWER_RECYCLE_VIEW);
    } else if ("create".equals(startnode))
      url = this.executeWithPermission("create", PERMISSION_LOWER_CREATE);
    else if ("edit".equals(startnode))
      url = this.executeWithPermission("edit", PERMISSION_LOWER_EDIT);
    else if ("delete".equals(startnode))
      url = this.executeWithPermission("delete", PERMISSION_LOWER_DELETE);
    else if ("undelete".equals(startnode))
      url = this.executeWithPermission("undelete", PERMISSION_LOWER_RECYCLE_UNDELETE);
    else if ("myOrg".equals(startnode))
      url = this.executeWithPermission("myOrg", PERMISSION_SELF_VIEW);
    else if ("myLowerOrgs".equals(startnode))
      url = this.executeWithPermission("myLowerOrgs", PERMISSION_LOWER_VIEW);
    else if ("myBrotherOrgs".equals(startnode))
      url = this.executeWithPermission("myBrotherOrgs", PERMISSION_BROTHER_VIEW);
    else if ("browse".equals(startnode))
      url = this.executeWithPermission("browse", null);
    else if ("viewOrgDomain".equals(startnode))
      url = this.executeWithPermission("viewOrgDomain", null);
    else if ("viewUsers".equals(startnode))
      url = this.executeWithPermission("viewUsers", ViewUserSystem.PERMISSION_VIEW);
    else if ("viewRoles".equals(startnode))
      url = this.executeWithPermission("viewRoles", ViewRoleSystem.PERMISSION_VIEW);
    else if ("dispatch".equals(startnode)) {
      String action = (String) dd.getFormValue("action");
      if (action == null)
        action = "filter";
      else if ("filter".equals(action))
        url = this.executeWithPermission("filter", null);
      else if ("list".equals(action))
        url = this.executeWithPermission("list", null);
      else if ("save".equals(action)) {
        String isRecycle = (String) dd.getFormValue("isRecycle");
        if ("true".equalsIgnoreCase(isRecycle)) {
          String uuid = (String) dd.getFormValue("org_uuid");
          if ("".equals(uuid))
            uuid = null;
          if (uuid == null)
            url = this.executeWithPermission("save", PERMISSION_LOWER_CREATE);
          else
            url = this.executeWithPermission("save", PERMISSION_LOWER_EDIT);
        } else
          url = this.executeWithPermission("save", PERMISSION_LOWER_RECYCLE_EDIT);
      }
    }
    // TODO Auto-generated method stub

    return url;
  }

  public String getPermission(String functionName, String orgUuid, Boolean isRecycle)
      throws BusinessException, HibernateException {
    BOrganization org = getBOrgMgr().loadOrganization(orgUuid);
    BOrganization currOrg = getBOrgMgr().loadOrganization(dd.getCurrentOrganization().getUuid());
    int relation = getBOrgMgr().getRelativePosition(currOrg, org);
    return getPermission(functionName, relation, isRecycle);
  }

  public String getPermission(String functionName, int relationship, Boolean isRecycle) {
    if (relationship == IBOrganizationMgr.VALUE_RELATIONSHIP_SELF) {
      if (ViewOrganization.FUNCTION_VIEW.equals(functionName))
        return PERMISSION_SELF_VIEW;
      else if (ViewOrganization.FUNCTION_EDIT.equals(functionName))
        return PERMISSION_SELF_EDIT;
    } else if (relationship == IBOrganizationMgr.VALUE_RELATIONSHIP_UPPER) {
      if (ViewOrganization.FUNCTION_VIEW.equals(functionName))
        return PERMISSION_UPPER_VIEW;
    } else if (relationship == IBOrganizationMgr.VALUE_RELATIONSHIP_BROTHER) {
      if (ViewOrganization.FUNCTION_VIEW.equals(functionName))
        return PERMISSION_BROTHER_VIEW;
    } else if (relationship == IBOrganizationMgr.VALUE_RELATIONSHIP_LOWER) {
      if (!isRecycle.booleanValue()) {
        if (ViewOrganization.FUNCTION_CREATE.equals(functionName))
          return PERMISSION_LOWER_CREATE;
        else if (ViewOrganization.FUNCTION_EDIT.equals(functionName))
          return PERMISSION_LOWER_EDIT;
        else if (ViewOrganization.FUNCTION_VIEW.equals(functionName))
          return PERMISSION_LOWER_VIEW;
        else if (ViewOrganization.FUNCTION_DELETE.equals(functionName))
          return PERMISSION_LOWER_DELETE;
      } else {
        if (ViewOrganization.FUNCTION_VIEW.equals(functionName))
          return PERMISSION_LOWER_RECYCLE_VIEW;
        else if (ViewOrganization.FUNCTION_EDIT.equals(functionName))
          return PERMISSION_LOWER_RECYCLE_EDIT;
        else if (ViewOrganization.FUNCTION_UNDELETE.equals(functionName))
          return PERMISSION_LOWER_RECYCLE_UNDELETE;
      }
    }
    return null;
  }

  protected void addForceFilter(BSQLSubquery bsq) throws BusinessException, HibernateException {
    SCE sce = new SCE(SCE.VALUE_OPERATOR_OR);
    BOrganization borg = getBOrgMgr().loadOrganization(getCurrentOrganization().getUuid());

    if (getCurrentUser().hasPermission(PERMISSION_SELF_VIEW)) {
      SCE cond = SCE.cond("o.uuid = ?", borg.getUuid());
      sce.append(cond);
    }

    if (getCurrentUser().hasPermission(PERMISSION_UPPER_VIEW)) {
      LevelCode levelCode = new LevelCode(COrganization.VALUE_LEVELIDRULE);
      List<String> levelIds = new ArrayList<String>();
      String levelId = levelCode.getParent(borg.getLevelId());
      while (levelId != null) {
        levelIds.add(levelId);
        levelId = levelCode.getParent(levelId);
      }
      if (levelIds.size() > 0) {
        SCE cond = SCE.cond("o.levelId in ?", levelIds.toArray());
        sce.append(cond);
      }
    }

    if (getCurrentUser().hasPermission(PERMISSION_BROTHER_VIEW)) {
      SCE and = new SCE(SCE.VALUE_OPERATOR_AND);
      if (borg.getUpperOrganization() != null)
        and.append(SCE.cond("o.upperOrganization.uuid = ?", borg.getUpperOrganization().getUuid()));
      else
        and.append(SCE.cond("o.upperOrganization is null"));
      and.append(SCE.cond("o.uuid != ?", borg.getUuid()));
      and.append(SCE.cond("o.state != ?", COrganization.VALUE_STATE_DELETED));
      sce.append(and);
    }

    PE pe = PE.OR(PE.P(PERMISSION_LOWER_VIEW), PE.P(PERMISSION_LOWER_RECYCLE_VIEW));
    if (getCurrentUser().hasPermissions(pe)) {
      SCE and = new SCE(SCE.VALUE_OPERATOR_AND);
      and.append(SCE.cond("o.levelId like ?", borg.getLevelId(), SCE.WC_RIGHT));
      and.append(SCE.cond("o.uuid != ?", borg.getUuid()));
      SCE or = new SCE(SCE.VALUE_OPERATOR_OR);
      if (getCurrentUser().hasPermission(PERMISSION_LOWER_VIEW))
        or.append(SCE.cond("o.state != ?", COrganization.VALUE_STATE_DELETED));
      if (getCurrentUser().hasPermission(PERMISSION_LOWER_RECYCLE_VIEW))
        or.append(SCE.cond("o.state = ?", COrganization.VALUE_STATE_DELETED));
      and.append(or);
      sce.append(and);
    }

    bsq.setWhereCondition(SCE.and(bsq.getWhereCondition(), sce));
  }

  protected boolean checkForceFilter(BOrganization borg, IUser currentUser, IOrganization currentOrg)
      throws Exception {
    BOrganization bcurrOrg = getBOrgMgr().loadOrganization(currentOrg.getUuid());
    int relation = getBOrgMgr().getRelativePosition(bcurrOrg, borg);
    if (IBOrganizationMgr.VALUE_RELATIONSHIP_SELF == relation)
      return currentUser.hasPermission(PERMISSION_SELF_VIEW);
    else if (IBOrganizationMgr.VALUE_RELATIONSHIP_UPPER == relation)
      return currentUser.hasPermission(PERMISSION_UPPER_VIEW);
    else if (IBOrganizationMgr.VALUE_RELATIONSHIP_BROTHER == relation)
      return currentUser.hasPermission(PERMISSION_BROTHER_VIEW);
    else if (IBOrganizationMgr.VALUE_RELATIONSHIP_LOWER == relation) {
      if (COrganization.VALUE_STATE_DELETED.equals(borg.getState()))
        return currentUser.hasPermission(PERMISSION_LOWER_RECYCLE_VIEW);
      else
        return currentUser.hasPermission(PERMISSION_LOWER_VIEW);
    }
    return false;
  }

  public String home() throws Exception {
    return showHome();
  }

  public String create() throws Exception {
    // dd.putFormValue("upperOrg_uuid", dd.getCurrentOrganization().getUuid());
    return super.create();
  }

  public String myOrg() throws Exception {
    dd.putFormValue("org_uuid", dd.getCurrentOrganization().getUuid());
    return view();
  }

  public String myLowerOrgs() throws Exception {
    dd.putFormValue("filter_upperOrg", dd.getCurrentOrganization().getUuid());
    return list();
  }

  public String myBrotherOrgs() throws Exception {
    if (dd.getCurrentOrganization().getUpperOrganization() != null)
      dd.putFormValue("filter_upperOrg", dd.getCurrentOrganization().getUpperOrganization()
          .getUuid());
    else
      dd.putFormValue("filter_upperOrg", null);
    dd.putFormValue("filter_exceptOrg", dd.getCurrentOrganization().getUuid());
    return list();
  }

  private String showHome() throws BusinessException, HibernateException {
    BOrganization myOrg = getBOrgMgr().loadOrganization(dd.getCurrentOrganization().getUuid());
    dd.put("myOrg", myOrg);
    Integer lowerCount = getBOrgMgr().getLowerOrganizationsCount(myOrg.getUuid(), false);
    dd.put("lowerCount", lowerCount);
    Integer brotherCount = getBOrgMgr().getBrotherOrganizationsCount(myOrg.getUuid());
    dd.put("brotherCount", brotherCount);
    dd.setWorkingTemplate(TEMPLATE_HOME);
    return ActionConstants.APPLICATIONFRAME;
  }

  protected int getListRelationship(OrganizationFilter filter) throws BusinessException,
      HibernateException {
    BOrganization bcurrOrg = getBOrgMgr().loadOrganization(this.getCurrentOrganization().getUuid());
    BOrganization upperOrg = null;
    if (filter.getUpperOrg() != null)
      upperOrg = getBOrgMgr().loadOrganization(filter.getUpperOrg().getUuid());
    else {
      if (bcurrOrg.getUpperOrganization() == null)
        return IBOrganizationMgr.VALUE_RELATIONSHIP_BROTHER;
      else
        return IBOrganizationMgr.VALUE_RELATIONSHIP_UPPER;
    }

    int upperRelation = getBOrgMgr().getRelativePosition(bcurrOrg, upperOrg);

    if (upperRelation == IBOrganizationMgr.VALUE_RELATIONSHIP_SELF)
      return IBOrganizationMgr.VALUE_RELATIONSHIP_LOWER;
    else if (upperRelation == IBOrganizationMgr.VALUE_RELATIONSHIP_LOWER)
      return IBOrganizationMgr.VALUE_RELATIONSHIP_LOWER;
    else if (upperRelation == IBOrganizationMgr.VALUE_RELATIONSHIP_BROTHER)
      return IBOrganizationMgr.VALUE_RELATIONSHIP_OTHER;
    else if (upperRelation == IBOrganizationMgr.VALUE_RELATIONSHIP_UPPER) {
      if (upperOrg == null && bcurrOrg.getUpperOrganization() == null)
        return IBOrganizationMgr.VALUE_RELATIONSHIP_BROTHER;
      else if (upperOrg != null && bcurrOrg.getUpperOrganization() != null
          && upperOrg.getUuid().equals(bcurrOrg.getUpperOrganization().getUuid()))
        return IBOrganizationMgr.VALUE_RELATIONSHIP_BROTHER;
      else
        return IBOrganizationMgr.VALUE_RELATIONSHIP_UPPER;
    } else
      return IBOrganizationMgr.VALUE_RELATIONSHIP_OTHER;
  }
}
